#!/usr/bin/env ruby
#
# Created by Jerry Luk on 2008-05-01
# Copyright (c) 2008. All rights reserved.

# Represents the Google Data
module RSS
  GDATA_PREFIX = 'gd'
  GDATA_URI = 'http://schemas.google.com/g/2005'
  
  module BaseGDataModel
    def append_features(klass)
      super
      base_append_features(klass, GDataModel::ELEMENT_NAME_INFOS, GDATA_PREFIX, GDATA_URI)
    end
  end
  
  module GDataModel
    extend BaseModel
    extend BaseGDataModel
    
    TEXT_ELEMENTS = [
      # [name, plural_name, content]
      ["feedLink",      nil,  false],
      ["comments",      nil,  false]
    ]
    
    ATTRIBUTES = [
      # [name, uri, required, type]
      ["value", "", false],
      ["href", "", false],
      ["email", "", false],
      ["rel", "", false],
      ["label", "", false],
      ["valueString", "", false],
      ["primary", "", false],
      ["id", "", false]
    ]
    
    ELEMENT_NAME_INFOS = GDataModel::TEXT_ELEMENTS.to_a
    ELEMENTS = TEXT_ELEMENTS.map(&:first)
    
    ELEMENT_NAME_INFOS.each do |name, plural_name, content|
      create_class(name, plural_name, GDATA_PREFIX, GDATA_URI, content)
    end
  end
    
  GDataModel::ELEMENTS.each do |name|
    class_name = Utils.to_class_name_with_prefix(name, GDATA_PREFIX)
    BaseListener.install_class_name(GDATA_URI, name, class_name)
  end
  
  GDataModel::ELEMENTS.collect! { |name| "#{GDATA_PREFIX}_#{name}"}
end

module RSS
  module Atom
    Feed.install_ns(GDATA_PREFIX, GDATA_URI)
    class Feed
      include GDataModel
      class Entry; include GDataModel; end
    end

    class Entry
      include GDataModel
    end
  end
  module GDataModel    
    class GdComments < Element
      install_have_child_element("feedLink", GDATA_URI, "*", "gd_feedLink")
      class GdFeedLink < GDataModel::GdFeedLink
        @tag_name = "feedLink"
      end
    end
  end
end

# Base Class for GData
module Google
  class GData
    attr_accessor :atom, :self_link, :alternate_link, :edit_link
    def initialize(atom_or_gdata=RSS::Atom::Entry.new)
      if atom_or_gdata.kind_of? GData
        @atom = atom_or_gdata.atom
      else
        @atom = atom_or_gdata
      end
    end
    
    def atom_id
      @atom.id.content if @atom
    end
    
    def to_xml
      @atom.to_xml if @atom
    end
    
    def to_s
      @atom.to_s if @atom
    end
    
    def self_link
      process_links unless @self_link
      @self_link 
    end
    
    def edit_link
      process_links unless @edit_link
      @edit_link
    end
    
    def alternate_link
      process_links unless @alternate_link
      @alternate_link
    end
    
    def title
      @atom.title.content
    end
    
    def title=(a_title)
      @atom.title = RSS::Atom::Feed::Title.new if @atom.title.nil?
      @atom.title.content = a_title
    end
    
    def method_missing(symbol, *params)
      @atom.send(symbol, *params) if @atom
    end
    
    private
    def process_links
      return unless @atom and @atom.links
      @atom.links.each do |l|
        @self_link = l.href if l.rel == 'self'
        @alternate_link = l.href if l.rel == 'alternate'
        @edit_link = l.href if l.rel == 'edit'
      end
    end
  end
end
